#ifndef ADISTRIBUTEDMODULE_H
#define ADISTRIBUTEDMODULE_H

#include "socket.hh"
#include "protocol.hh"
#include "thread.hh"
#include "mutex.hh"
#include <iostream>
#include <string>

using namespace NM;
using namespace std;
using namespace DLIB_PROTO;

class ADistributedModule : Thread, Mutex
{
private: // variables reserved to the module prototype
    bool _ready;                // mutex protected
    bool _error;
    bool _canFail;
    bool _executed;

    string _path;
    string _factory;

public: // interface
    ADistributedModule(string modulePath, string factorySymbol);
    virtual ~ADistributedModule() = 0;

    virtual bool LoadData(void *data) = 0;
    virtual bool ExportData(void **data, int *size) = 0;

    virtual bool ExecuteLocal();
    virtual void ExecuteDistributed(bool canFail = false);
    string GetFactorySymbol();
    bool IsReady();
    bool ExecutionFailed();
    void Stop();

    void distribute();          // DO NOT CALL THIS FUNCTION (thread reserved)

protected:
    virtual bool executeLocal() = 0;

private: // module prototype internals
    void setReady(bool val);
    void start();
};

void *distributed_module_starter(void *data);

#endif // ADISTRIBUTEDMODULE_H
